#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_clk_tree.h"
#include "soc/soc_caps.h"
#include "driver/gptimer.h"      // 为了使用 SOC_GPTIMER_CLKS

static const char *TAG = "clk_tree";

/**
 * @brief       程序入口
 * @param       无
 * @retval      无
 */
void app_main(void)
{
    /* 1. CPU 时钟 */
    uint32_t cpu_clk = 0;
    esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_CPU, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &cpu_clk);
    ESP_LOGI(TAG, "CPU_CLK  = %" PRIu32 " Hz", cpu_clk);

    /* 2. APB 总线时钟 */
    uint32_t apb_clk = 0;
    esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_APB, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &apb_clk);
    ESP_LOGI(TAG, "APB_CLK  = %" PRIu32 " Hz", apb_clk);

    /* 3. LEDC 控制器时钟（与 APB 相同）*/
    uint32_t ledc_clk = 0;
    esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_APB, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &ledc_clk);
    ESP_LOGI(TAG, "LEDC_CLK = %" PRIu32 " Hz (same as APB on S3)", ledc_clk);

    /* 4. GPTimer 可用时钟源 */
    soc_periph_gptimer_clk_src_t gptimer_clks[] = {
        GPTIMER_CLK_SRC_APB,
        GPTIMER_CLK_SRC_XTAL,
        SOC_MOD_CLK_PLL_F80M
    };
    for (size_t i = 0; i < sizeof(gptimer_clks)/sizeof(gptimer_clks[0]); ++i) {
        uint32_t freq = 0;
        esp_clk_tree_src_get_freq_hz(gptimer_clks[i], ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
        ESP_LOGI(TAG, "GPTimer[%zu] clk = %" PRIu32 " Hz", i, freq);
    }

    while(1)
    {
        vTaskDelay(500);   /* 延时500ms */
    }
}
